#![allow(dead_code, mutable_transmutes, non_camel_case_types, non_snake_case, non_upper_case_globals, unused_assignments, unused_mut)]
use std::mem;
use crate::alloc_testing::*;
extern "C" {
            }
pub type size_t = libc::c_ulong;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _Set {
    pub table: *mut *mut SetEntry,
    pub entries: libc::c_uint,
    pub table_size: libc::c_uint,
    pub prime_index: libc::c_uint,
    pub hash_func: SetHashFunc,
    pub equal_func: SetEqualFunc,
    pub free_func: SetFreeFunc,
}
pub type SetFreeFunc = Option::<unsafe extern "C" fn(SetValue) -> ()>;
pub type SetValue = *mut libc::c_void;
pub type SetEqualFunc = Option::<
    unsafe extern "C" fn(SetValue, SetValue) -> libc::c_int,
>;
pub type SetHashFunc = Option::<unsafe extern "C" fn(SetValue) -> libc::c_uint>;
pub type SetEntry = _SetEntry;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _SetEntry {
    pub data: SetValue,
    pub next: *mut SetEntry,
}
pub type Set = _Set;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct _SetIterator {
    pub set: *mut Set,
    pub next_entry: *mut SetEntry,
    pub next_chain: libc::c_uint,
}
pub type SetIterator = _SetIterator;
static mut set_primes: [libc::c_uint; 24] = [
    193 as libc::c_int as libc::c_uint,
    389 as libc::c_int as libc::c_uint,
    769 as libc::c_int as libc::c_uint,
    1543 as libc::c_int as libc::c_uint,
    3079 as libc::c_int as libc::c_uint,
    6151 as libc::c_int as libc::c_uint,
    12289 as libc::c_int as libc::c_uint,
    24593 as libc::c_int as libc::c_uint,
    49157 as libc::c_int as libc::c_uint,
    98317 as libc::c_int as libc::c_uint,
    196613 as libc::c_int as libc::c_uint,
    393241 as libc::c_int as libc::c_uint,
    786433 as libc::c_int as libc::c_uint,
    1572869 as libc::c_int as libc::c_uint,
    3145739 as libc::c_int as libc::c_uint,
    6291469 as libc::c_int as libc::c_uint,
    12582917 as libc::c_int as libc::c_uint,
    25165843 as libc::c_int as libc::c_uint,
    50331653 as libc::c_int as libc::c_uint,
    100663319 as libc::c_int as libc::c_uint,
    201326611 as libc::c_int as libc::c_uint,
    402653189 as libc::c_int as libc::c_uint,
    805306457 as libc::c_int as libc::c_uint,
    1610612741 as libc::c_int as libc::c_uint,
];
static mut set_num_primes: libc::c_uint = 0;
extern "C" fn set_allocate_table(mut set: *mut Set) -> libc::c_int {
    let table_size: libc::c_uint;
    let table: *mut *mut SetEntry;

    let mut boxed_set = unsafe { Box::from_raw(set) };

    if boxed_set.prime_index < unsafe { set_num_primes } {
        table_size = unsafe { set_primes[boxed_set.prime_index as usize] };
    } else {
        table_size = (boxed_set.entries).wrapping_mul(10);
    }

    boxed_set.table_size = table_size;
    table = alloc_test_calloc(
        table_size as size_t,
        std::mem::size_of::<*mut SetEntry>() as libc::c_ulong,
    ) as *mut *mut SetEntry;

    boxed_set.table = table;
    set = Box::into_raw(boxed_set);

    return (table != std::ptr::null_mut()) as libc::c_int;
}
extern "C" fn set_free_entry(mut set: *mut Set, mut entry: *mut SetEntry) {
    if !set.is_null() && !entry.is_null() {
        let boxed_set = unsafe { Box::from_raw(set) };
        let boxed_entry = unsafe { Box::from_raw(entry) };
        if boxed_set.free_func.is_some() {
            unsafe {
                boxed_set.free_func.expect("non-null function pointer")(boxed_entry.data);
            }
        }
        alloc_test_free(entry as *mut libc::c_void);
        let set = Box::into_raw(boxed_set);
        let entry = Box::into_raw(boxed_entry);
    }
}
#[no_mangle]
pub extern "C" fn set_new(
    hash_func: SetHashFunc,
    equal_func: SetEqualFunc,
) -> *mut Set {
    let new_set: *mut Set = unsafe {
        alloc_test_malloc(std::mem::size_of::<Set>() as libc::c_ulong) as *mut Set
    };

    if new_set.is_null() {
        return std::ptr::null_mut();
    }

    let mut boxed_set = unsafe { Box::from_raw(new_set) };
    boxed_set.hash_func = hash_func;
    boxed_set.equal_func = equal_func;
    boxed_set.entries = 0;
    boxed_set.prime_index = 0;
    boxed_set.free_func = None;

    if set_allocate_table(new_set) == 0 {
        alloc_test_free(new_set as *mut libc::c_void);
        return std::ptr::null_mut();
    }

    let new_set = Box::into_raw(boxed_set);
    new_set
}
#[no_mangle]
pub extern "C" fn set_free(mut set: *mut Set) {
    if !set.is_null() {
        let boxed_set = unsafe { Box::from_raw(set) };
        let mut rover: *mut SetEntry = std::ptr::null_mut();
        let mut next: *mut SetEntry = std::ptr::null_mut();
        let mut i: libc::c_uint = 0;

        while i < boxed_set.table_size {
            rover = unsafe { *boxed_set.table.offset(i as isize) };
            while !rover.is_null() {
                next = unsafe { (*rover).next };
                set_free_entry(set, rover);
                rover = next;
            }
            i = i.wrapping_add(1);
        }
        alloc_test_free(boxed_set.table as *mut libc::c_void);
        alloc_test_free(set as *mut libc::c_void);
        let set = Box::into_raw(boxed_set);
    }
}
#[no_mangle]
pub extern "C" fn set_register_free_function(
    mut set: *mut Set,
    mut free_func: SetFreeFunc,
) {
    let mut boxed_set = unsafe { Box::from_raw(set) };
    boxed_set.free_func = free_func;
    let set = Box::into_raw(boxed_set);
}
extern "C" fn set_enlarge(mut set: *mut Set) -> libc::c_int {
    let mut rover: *mut SetEntry = std::ptr::null_mut();
    let mut next: *mut SetEntry = std::ptr::null_mut();
    let mut old_table: *mut *mut SetEntry = std::ptr::null_mut();
    let mut old_table_size: libc::c_uint = 0;
    let mut old_prime_index: libc::c_uint = 0;
    let mut index: libc::c_uint = 0;
    let mut i: libc::c_uint = 0;

    let mut boxed_set = unsafe { Box::from_raw(set) };
    old_table = boxed_set.table;
    old_table_size = boxed_set.table_size;
    old_prime_index = boxed_set.prime_index;
    boxed_set.prime_index = boxed_set.prime_index.wrapping_add(1);

    if set_allocate_table(set) == 0 {
        boxed_set.table = old_table;
        boxed_set.table_size = old_table_size;
        boxed_set.prime_index = old_prime_index;
        set = Box::into_raw(boxed_set);
        return 0;
    }

    i = 0;
    while i < old_table_size {
        unsafe {
            rover = *old_table.offset(i as isize);
        }
        while !rover.is_null() {
            unsafe {
                next = (*rover).next;
                index = (boxed_set.hash_func)
                    .expect("non-null function pointer")((*rover).data)
                    .wrapping_rem(boxed_set.table_size);
                (*rover).next = *boxed_set.table.offset(index as isize);
                let ref mut fresh0 = *boxed_set.table.offset(index as isize);
                *fresh0 = rover;
                rover = next;
            }
        }
        i = i.wrapping_add(1);
    }

    unsafe {
        alloc_test_free(old_table as *mut libc::c_void);
    }

    set = Box::into_raw(boxed_set);
    return 1;
}
#[no_mangle]
pub extern "C" fn set_insert(
    mut set: *mut Set,
    mut data: SetValue,
) -> libc::c_int {
    let mut newentry: *mut SetEntry = std::ptr::null_mut();
    let mut rover: *mut SetEntry = std::ptr::null_mut();
    let mut index: libc::c_uint = 0;

    let mut boxed_set = unsafe { Box::from_raw(set) };

    if (boxed_set.entries as libc::c_uint)
        .wrapping_mul(3)
        .wrapping_div(boxed_set.table_size) > 0
    {
        if set_enlarge(set) == 0 {
            set = Box::into_raw(boxed_set);
            return 0;
        }
    }

    index = unsafe { (boxed_set.hash_func.unwrap())(data).wrapping_rem(boxed_set.table_size) };
    rover = unsafe { *boxed_set.table.offset(index as isize) };

    while !rover.is_null() {
        if unsafe { (boxed_set.equal_func.unwrap())(data, (*rover).data) != 0 } {
            set = Box::into_raw(boxed_set);
            return 0;
        }
        rover = unsafe { (*rover).next };
    }

    newentry = unsafe {
        alloc_test_malloc(std::mem::size_of::<SetEntry>() as libc::c_ulong) as *mut SetEntry
    };
    if newentry.is_null() {
        set = Box::into_raw(boxed_set);
        return 0;
    }

    unsafe {
        (*newentry).data = data;
        (*newentry).next = *boxed_set.table.offset(index as isize);
        let ref mut fresh1 = *boxed_set.table.offset(index as isize);
        *fresh1 = newentry;
        boxed_set.entries = boxed_set.entries.wrapping_add(1);
    }

    set = Box::into_raw(boxed_set);
    return 1;
}
#[no_mangle]
pub extern "C" fn set_remove(
    mut set: *mut Set,
    mut data: SetValue,
) -> libc::c_int {
    let mut boxed_set = unsafe { Box::from_raw(set) };
    let mut rover: *mut *mut SetEntry = std::ptr::null_mut();
    let mut entry: *mut SetEntry = std::ptr::null_mut();
    let mut index: libc::c_uint = 0;
    unsafe {
        index = (boxed_set.hash_func.expect("non-null function pointer")(data))
            .wrapping_rem(boxed_set.table_size);
        rover = &mut *boxed_set.table.offset(index as isize) as *mut *mut SetEntry;
        while !(*rover).is_null() {
            if boxed_set.equal_func.expect("non-null function pointer")(data, (**rover).data)
                != 0 as libc::c_int
            {
                entry = *rover;
                *rover = (*entry).next;
                boxed_set.entries = boxed_set.entries.wrapping_sub(1);
                set_free_entry(set, entry);
                set = Box::into_raw(boxed_set);
                return 1 as libc::c_int;
            }
            rover = &mut (**rover).next;
        }
    }
    set = Box::into_raw(boxed_set);
    return 0 as libc::c_int;
}
#[no_mangle]
pub extern "C" fn set_query(
    mut set: *mut Set,
    mut data: SetValue,
) -> libc::c_int {
    let mut rover: *mut SetEntry = std::ptr::null_mut();
    let mut index: libc::c_uint = 0;

    let boxed_set = unsafe { Box::from_raw(set) };
    index = unsafe { (boxed_set.hash_func.expect("non-null function pointer"))(data) }
        .wrapping_rem(boxed_set.table_size);
    rover = unsafe { *boxed_set.table.offset(index as isize) };

    while !rover.is_null() {
        if unsafe {
            (boxed_set.equal_func.expect("non-null function pointer"))(data, (*rover).data)
                != 0
        } {
            set = Box::into_raw(boxed_set);
            return 1;
        }
        rover = unsafe { (*rover).next };
    }

    set = Box::into_raw(boxed_set);
    return 0;
}
#[no_mangle]
pub extern "C" fn set_num_entries(set: *mut Set) -> libc::c_uint {
    let boxed_set = unsafe { Box::from_raw(set) };
    let entries = boxed_set.entries;
    let set = Box::into_raw(boxed_set);
    entries
}
#[no_mangle]
pub extern "C" fn set_to_array(mut set: *mut Set) -> *mut SetValue {
    let mut array: *mut SetValue = std::ptr::null_mut();
    let mut array_counter: libc::c_int = 0;
    let mut i: libc::c_uint = 0;
    let mut rover: *mut SetEntry = std::ptr::null_mut();

    let boxed_set = unsafe { Box::from_raw(set) };
    array = unsafe {
        alloc_test_malloc(
            (std::mem::size_of::<SetValue>() as libc::c_ulong)
                .wrapping_mul(boxed_set.entries as libc::c_ulong),
        ) as *mut SetValue
    };

    if array.is_null() {
        set = Box::into_raw(boxed_set);
        return std::ptr::null_mut();
    }

    array_counter = 0;
    i = 0;

    while i < boxed_set.table_size {
        rover = unsafe { *boxed_set.table.offset(i as isize) };
        while !rover.is_null() {
            unsafe {
                *array.offset(array_counter as isize) = (*rover).data;
            }
            array_counter += 1;
            rover = unsafe { (*rover).next };
        }
        i = i.wrapping_add(1);
    }

    set = Box::into_raw(boxed_set);
    array
}
#[no_mangle]
pub extern "C" fn set_iterate(mut set: *mut Set, mut iter: *mut SetIterator) {
    let mut boxed_iter = unsafe { Box::from_raw(iter) };
    boxed_iter.set = set;
    boxed_iter.next_entry = std::ptr::null_mut();
    let mut chain: libc::c_uint = 0;
    while chain < unsafe { (*set).table_size } {
        if !unsafe { *((*set).table).offset(chain as isize) }.is_null() {
            boxed_iter.next_entry = unsafe { *((*set).table).offset(chain as isize) };
            break;
        } else {
            chain = chain.wrapping_add(1);
        }
    }
    boxed_iter.next_chain = chain;
    iter = Box::into_raw(boxed_iter);
}
#[no_mangle]
pub extern "C" fn set_iter_next(mut iterator: *mut SetIterator) -> SetValue {
    let mut set: *mut Set = std::ptr::null_mut();
    let mut result: SetValue = std::ptr::null_mut();
    let mut current_entry: *mut SetEntry = std::ptr::null_mut();
    let mut chain: libc::c_uint = 0;

    let mut boxed_iterator = unsafe { Box::from_raw(iterator) };
    set = boxed_iterator.set;
    if boxed_iterator.next_entry.is_null() {
        iterator = Box::into_raw(boxed_iterator);
        return std::ptr::null_mut();
    }
    current_entry = boxed_iterator.next_entry;
    result = unsafe { (*current_entry).data };
    if !unsafe { (*current_entry).next }.is_null() {
        boxed_iterator.next_entry = unsafe { (*current_entry).next };
    } else {
        boxed_iterator.next_entry = std::ptr::null_mut();
        chain = boxed_iterator.next_chain.wrapping_add(1);
        while chain < unsafe { (*set).table_size } {
            if !unsafe { *((*set).table).offset(chain as isize) }.is_null() {
                boxed_iterator.next_entry = unsafe { *((*set).table).offset(chain as isize) };
                break;
            } else {
                chain = chain.wrapping_add(1);
            }
        }
        boxed_iterator.next_chain = chain;
    }
    iterator = Box::into_raw(boxed_iterator);
    result
}
#[no_mangle]
pub extern "C" fn set_iter_has_more(
    mut iterator: *mut SetIterator,
) -> libc::c_int {
    let boxed_iterator = unsafe { Box::from_raw(iterator) };
    let result = (boxed_iterator.next_entry != std::ptr::null_mut()) as libc::c_int;
    let iterator = Box::into_raw(boxed_iterator);
    result
}
#[no_mangle]
pub extern "C" fn set_union(mut set1: *mut Set, mut set2: *mut Set) -> *mut Set {
    let mut iterator: SetIterator = _SetIterator {
        set: std::ptr::null_mut(),
        next_entry: std::ptr::null_mut(),
        next_chain: 0,
    };
    let mut new_set: *mut Set = std::ptr::null_mut();
    let mut value: SetValue = std::ptr::null_mut();

    let boxed_set1 = unsafe { Box::from_raw(set1) };
    let boxed_set2 = unsafe { Box::from_raw(set2) };

    new_set = set_new(boxed_set1.hash_func, boxed_set1.equal_func);

    if new_set.is_null() {
        set1 = Box::into_raw(boxed_set1);
        set2 = Box::into_raw(boxed_set2);
        return std::ptr::null_mut();
    }

    set_iterate(set1, &mut iterator);

    while set_iter_has_more(&mut iterator) != 0 {
        value = set_iter_next(&mut iterator);
        if set_insert(new_set, value) == 0 {
            set_free(new_set);
            set1 = Box::into_raw(boxed_set1);
            set2 = Box::into_raw(boxed_set2);
            return std::ptr::null_mut();
        }
    }

    set_iterate(set2, &mut iterator);

    while set_iter_has_more(&mut iterator) != 0 {
        value = set_iter_next(&mut iterator);
        if set_query(new_set, value) == 0 {
            if set_insert(new_set, value) == 0 {
                set_free(new_set);
                set1 = Box::into_raw(boxed_set1);
                set2 = Box::into_raw(boxed_set2);
                return std::ptr::null_mut();
            }
        }
    }

    set1 = Box::into_raw(boxed_set1);
    set2 = Box::into_raw(boxed_set2);
    new_set
}
#[no_mangle]
pub extern "C" fn set_intersection(
    mut set1: *mut Set,
    mut set2: *mut Set,
) -> *mut Set {
    let mut new_set: *mut Set = std::ptr::null_mut();
    let mut iterator: SetIterator = _SetIterator {
        set: std::ptr::null_mut(),
        next_entry: std::ptr::null_mut(),
        next_chain: 0,
    };
    let mut value: SetValue = std::ptr::null_mut();

    let boxed_set1 = unsafe { Box::from_raw(set1) };
    let boxed_set2 = unsafe { Box::from_raw(set2) };

    new_set = set_new(boxed_set1.hash_func, boxed_set2.equal_func);

    if new_set.is_null() {
        set1 = Box::into_raw(boxed_set1);
        set2 = Box::into_raw(boxed_set2);
        return std::ptr::null_mut();
    }

    set_iterate(set1, &mut iterator);

    while set_iter_has_more(&mut iterator) != 0 {
        value = set_iter_next(&mut iterator);

        if set_query(set2, value) != 0 {
            if set_insert(new_set, value) == 0 {
                set_free(new_set);
                set1 = Box::into_raw(boxed_set1);
                set2 = Box::into_raw(boxed_set2);
                return std::ptr::null_mut();
            }
        }
    }

    set1 = Box::into_raw(boxed_set1);
    set2 = Box::into_raw(boxed_set2);
    new_set
}
extern "C" fn run_static_initializers() {
    unsafe {
        set_num_primes = (std::mem::size_of::<[libc::c_uint; 24]>() as libc::c_ulong)
            .wrapping_div(std::mem::size_of::<libc::c_int>() as libc::c_ulong)
            as libc::c_uint;
    }
}
#[used]
#[cfg_attr(target_os = "linux", link_section = ".init_array")]
#[cfg_attr(target_os = "windows", link_section = ".CRT$XIB")]
#[cfg_attr(target_os = "macos", link_section = "__DATA,__mod_init_func")]
static INIT_ARRAY: [unsafe extern "C" fn(); 1] = [run_static_initializers];
